﻿#define _CRT_SECURE_NO_WARNINGS 1

//6.修改默认对齐数
//#include <stdio.h>
//#pragma pack(1)  //设置默认对齐数为1
//struct S1
//{
//	char c1;
//	int i;
//	char c2;
//};
//#pragma pack()  //取消设置的默认对齐数, 还原为默认
//int main()
//{
//	printf("%d\n", sizeof(struct S1));
//
//	return 0;
//}

//7.结构体传参
//#include <stdio.h>
//struct S
//{
//	int data[1000];
//	int num;
//};
//struct S s = { {1,2,3,4}, 1000 };
////结构体传参
//void print1(struct S s)
//{
//	printf("%d\n", s.num);
//}
////结构体地址传参
//void print2(struct S* ps)
//{
//	printf("%d\n", ps->num);
//}
//int main()
//{
//	print1(s);  //传结构体
//	print2(&s);  //传地址
//	return 0;
//}

//上面的 print1 和 print2 函数哪个好些?
//答案是:首选print2函数
//原因:
//函数传参的时候, 参数是需要压栈的, 会有时间和空间上的系统开销
//如果传递一个结构体对象的时候, 结构体过大, 参数压栈的的系统开销比较大, 会导致性能的下降

//什么是位段
//1.位段的成员必须是 int 或 unsigned int 或 signed int
//2.位段的成员名后边有一个冒号和一个数字
//位段-位:二进制位
//struct A
//{
//	int _a : 2;  //2bit
//	int _b : 5;  //5bit
//	int _c : 10;  //10bit
//	int _d : 30;  //30bit
//};
//
//int main()
//{
//	printf("%d\n", sizeof(struct A));  //8
//	return 0;
//}

//VS2019上验证：位段的内存开辟和使用
//
//struct S
//{
//	char a : 3;
//	char b : 4;
//	char c : 5;
//	char d : 4;
//};
//
//int main()
//{
//	struct S s = { 0 };
//	s.a = 10;
//	s.b = 12;
//	s.c = 3;
//	s.d = 4;
//	printf("%d\n", sizeof(s));  //3
//
//	return 0;
//}

//位段的内存分配
//1.位段的成员可以是 int, unsigned int, signed int 或者是 char(属于整形家族)类型
//2.位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的
//3.位段涉及很多不确定因素, 位段是不跨平台的, 注重可移植的程序应该避免使用位段

//位段的跨平台问题
//1.int位段被当成有符号数还是无符号数是不确定的
//2.位段中最大位的数目不能确定(16位机器最大16, 32位机器最大32, 写成27, 在16位机器会出问题)
//3.位段中的成员在内存中从左向右分配, 还是从右向左分配标准尚未定义
//4.当一个结构包含两个位段, 第二个位段成员比较大, 无法容纳于第一个位段剩余的位时, 是舍弃剩余的位还是利用, 这是不确定的